package com.starlight.flower_server.domain.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.starlight.flower_server.controller.exception.ForbiddenException;
import com.starlight.flower_server.controller.exception.BadRequestException;
import com.starlight.flower_server.controller.exception.NotFoundException;
import com.starlight.flower_server.domain.TotalData;
import com.starlight.flower_server.domain.flowerUser.cqrs.FlowerUserPageQuery;
import com.starlight.flower_server.domain.flowerUser.data.FlowerUserData;
import com.starlight.flower_server.domain.flowerUser.data.TokenData;
import com.starlight.flower_server.infrastructure.Status;
import com.starlight.flower_server.infrastructure.entity.*;
import com.starlight.flower_server.infrastructure.repository.FlowerUserRoleRepository;
import com.starlight.flower_server.infrastructure.repository.LoginInfoRepository;
import com.starlight.flower_server.infrastructure.repository.OrderRepository;
import com.starlight.flower_server.infrastructure.util.JwtUtils;
import com.starlight.flower_server.infrastructure.repository.FlowerUserRepository;
import com.starlight.flower_server.domain.service.FlowerUserService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @Author yfy2001
 * @date 2023/4/5 15:05
 */
@Service
public class FlowerUserServiceImpl implements FlowerUserService {

    @Resource
    private FlowerUserRepository flowerUserRepository;

    @Resource
    private FlowerUserRoleRepository flowerUserRoleRepository;

    @Resource
    private OrderRepository orderRepository;

    @Resource
    private LoginInfoRepository loginInfoRepository;

    @Resource
    private JwtUtils jwtUtils;

    @Resource
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public Integer insertUser(FlowerUser flowerUser) {
        if (flowerUserRepository.exists(flowerUser)){
            throw new BadRequestException(Status.USER_ALREADY_EXISTS.getMessage(), Status.USER_ALREADY_EXISTS);
        }
        //encode密码加密存储
        String password=flowerUser.getPassword();
        BCryptPasswordEncoder bCryptPasswordEncoder=new BCryptPasswordEncoder();
        String encodedPassword= bCryptPasswordEncoder.encode(password);
        flowerUser.setPassword(encodedPassword);
        Integer i= flowerUserRepository.insert(flowerUser);
        if(!i.equals(0)){
            //注册成功赋予基本权限
            FlowerUserRole flowerUserRole=new FlowerUserRole();
            flowerUserRole.setFlowerUserId(flowerUser.getId());
            flowerUserRole.setRoleId(2L);
            flowerUserRoleRepository.insert(flowerUserRole);
        }else {
            throw new BadRequestException("注册失败：注册异常。",Status.ERROR);
        }
        return i;
    }

    @Override
    public TokenData login(FlowerUser flowerUser) {
        System.out.println(flowerUser.toString());
        FlowerUser loginUser= flowerUserRepository.queryOneByUserDetail(flowerUser);
        if (loginUser==null){
            throw new ForbiddenException(Status.INCORRECT_USERNAME_OR_PASSWORD.getMessage(),
                    Status.INCORRECT_USERNAME_OR_PASSWORD);
        }
        System.out.println(loginUser.getUsername());
        //密码加密后判断是否相同
        BCryptPasswordEncoder bCryptPasswordEncoder=new BCryptPasswordEncoder();
        if (!bCryptPasswordEncoder.matches(flowerUser.getPassword(),loginUser.getPassword())){
            throw new ForbiddenException(Status.INCORRECT_USERNAME_OR_PASSWORD.getMessage(),
                    Status.INCORRECT_USERNAME_OR_PASSWORD);
        }
        //登录成功生成token
        TokenData tokenData=new TokenData();
        tokenData.setFlowerUserId(loginUser.getId());
        tokenData.setToken(jwtUtils.generateToken(loginUser));
        return tokenData;
    }

    @Override
    public String logout(String token) {
        redisTemplate.delete(token);
        return "退出成功";
    }

    @Override
    public FlowerUser queryUserDetailById(Long id) {
        FlowerUser flowerUser=flowerUserRepository.queryDetail(id);
        if (flowerUser==null){
            throw new NotFoundException(Status.RECORD_NOT_FOUND.getMessage(),Status.RECORD_NOT_FOUND);
        }
        return flowerUser;
    }

    @Override
    public Integer logicDeleteUserById(Long id) {
        //查询是否有未完成订单
        List<Order> orderList=orderRepository.queryUnaccomplishedListByFlowerUserId(id);
        if (orderList.isEmpty()){
            FlowerUserRole flowerUserRole=flowerUserRoleRepository.queryOneByUserId(id);
            Integer i= flowerUserRepository.logicDelete(id);
            if (!i.equals(0)){
                //删除用户后移除其权限
                flowerUserRoleRepository.logicDelete(flowerUserRole.getId());
                //移除所有登录记录
                loginInfoRepository.removeAllByFlowerUserId(id);
                return i;
            }else {
                throw new NotFoundException(Status.RECORD_NOT_FOUND.getMessage(),Status.RECORD_NOT_FOUND);
            }
        }else {
            throw new BadRequestException(Status.USER_WITH_ORDER.getMessage(),Status.USER_WITH_ORDER);
        }
    }

    @Override
    public Integer modifyUser(FlowerUser flowerUser) {
        if (flowerUser.getId()==null){
            FlowerUser oldFlowerUser=flowerUserRepository.queryOneByUserDetail(flowerUser);
            if (oldFlowerUser==null){
                throw new NotFoundException(Status.USER_NOT_FOUND.getMessage(),Status.USER_NOT_FOUND);
            }
            flowerUser.setId(oldFlowerUser.getId());
        }
        if (flowerUserRepository.exists(flowerUser)){
            throw new BadRequestException(Status.USER_ALREADY_EXISTS.getMessage(), Status.USER_ALREADY_EXISTS);
        }
        if(flowerUser.getPassword()!=null){
            String password=flowerUser.getPassword();
            BCryptPasswordEncoder bCryptPasswordEncoder=new BCryptPasswordEncoder();
            String encodedPassword= bCryptPasswordEncoder.encode(password);
            flowerUser.setPassword(encodedPassword);
        }
        return flowerUserRepository.modify(flowerUser);
    }

    @Override
    public Integer resetPassword(FlowerUser flowerUser) {
        if(flowerUser.getPassword()!=null){
            String password=flowerUser.getPassword();
            BCryptPasswordEncoder bCryptPasswordEncoder=new BCryptPasswordEncoder();
            String encodedPassword= bCryptPasswordEncoder.encode(password);
            flowerUser.setPassword(encodedPassword);
        }
        return flowerUserRepository.modify(flowerUser);
    }

    @Override
    public Integer resetEmail(FlowerUser flowerUser) {
        if (flowerUserRepository.exists(flowerUser)){
            throw new BadRequestException(Status.USER_ALREADY_EXISTS.getMessage(), Status.USER_ALREADY_EXISTS);
        }
        return flowerUserRepository.modify(flowerUser);
    }

    @Override
    public Long userExists(FlowerUser flowerUser) {
        FlowerUser existsUser=flowerUserRepository.queryOneByUserDetail(flowerUser);
        if (existsUser!=null){
            return existsUser.getId();
        }else {
            return 0L;
        }
    }

    @Override
    public IPage<FlowerUserData> queryUserList(FlowerUserPageQuery query) {
        IPage<FlowerUser> page=flowerUserRepository.queryUserPage(query);
        return page.convert(flowerUser ->{
            FlowerUserData flowerUserData=new FlowerUserData();
            BeanUtils.copyProperties(flowerUser,flowerUserData);
            return flowerUserData;
        });
    }

    @Override
    public TotalData<FlowerUserData> queryAllFlowerUserData() {
        TotalData<FlowerUserData> data=new TotalData<>();
        List<FlowerUser> flowerUserList=flowerUserRepository.queryAll();
        List<FlowerUserData> flowerUserDataList=flowerUserList
                .stream().map(flowerUser -> {
                    FlowerUserData flowerUserData=new FlowerUserData();
                    BeanUtils.copyProperties(flowerUser,flowerUserData);
                    return flowerUserData;
                }).toList();
        Long total= (long) flowerUserDataList.size();
        data.setTable("FlowerUser");
        data.setStatTime(new Date());
        data.setTotal(total);
        data.setRecords(flowerUserDataList);
        return data;

    }

    @Override
    public TotalData<FlowerUserData> queryFlowerUserTotalCount() {
        TotalData<FlowerUserData> data=new TotalData<>();
        Long total=flowerUserRepository.queryTotalCount();
        data.setTable("FlowerUser");
        data.setStatTime(new Date());
        data.setTotal(total);
        return data;
    }
}
